package com.example.clipsync;

import android.content.ClipData;
import android.util.Log;

import java.lang.reflect.Method;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;

/**
 * 剪贴板钩子类
 * 用于通过 Xposed 框架监听系统剪贴板内容的变化
 */
public class ClipboardHooker {
    // 日志标签
    private static final String TAG = "GlobalClipboardLS";

    /**
     * 注册剪贴板钩子
     * @param classLoader 类加载器，用于查找系统剪贴板服务类
     */
    public static void hook(ClassLoader classLoader) {
        // 可能的剪贴板服务实现类名
        String[] candidates = new String[]{
                "com.android.server.clipboard.ClipboardService",
                "com.android.server.clipboard.ClipboardService$ClipboardImpl",
                "com.android.server.clipboard.ClipboardServiceImpl"
        };

        // 遍历所有可能的剪贴板服务类
        for (String cls : candidates) {
            try {
                // 查找类
                Class<?> clazz = XposedHelpers.findClass(cls, classLoader);
                XposedBridge.log(TAG + ": 已找到类 " + cls);

                // 遍历类中的所有方法
                for (Method m : clazz.getDeclaredMethods()) {
                    // 找到 setPrimaryClip 方法（设置剪贴板内容的方法）
                    if (m.getName().equals("setPrimaryClip")) {
                        XposedBridge.log(TAG + ": 正在 hook 方法 -> " + m.toString());

                        // 对 setPrimaryClip 方法进行 hook
                        XposedBridge.hookMethod(m, new XC_MethodHook() {
                            @Override
                            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                try {
                                    // 获取剪贴板数据对象
                                    ClipData clip = (ClipData) param.args[0];
                                    // 检查是否有有效的剪贴板内容
                                    if (clip != null && clip.getItemCount() > 0) {
                                        // 获取剪贴板文本
                                        CharSequence cs = clip.getItemAt(0).coerceToText(null);
                                        if (cs == null) return;
                                        String text = cs.toString();

                                        // 跳过重复内容（自己写入的）
                                        if (text.equals(ClipboardUtils.getLastWrittenText())) {
                                            return;
                                        }
                                        // 通过 WebSocket 发送剪贴板内容
                                        WsManager manager = WsManager.getInstance();
                                        if (manager != null) {
                                            manager.enqueueMessage(text);
                                        }
                                    }
                                } catch (Throwable e) {
                                    XposedBridge.log(TAG + ": 剪贴板 hook 出错 -> " + Log.getStackTraceString(e));
                                }
                            }
                        });
                    }
                }
            } catch (Throwable t) {
                XposedBridge.log(TAG + ": 未找到类 -> " + cls);
            }
        }
    }
}